<?php
use frontend\modules\yii2\widgets\layouts\markdown\Markdown;
/* @var $this \yii\web\View */
$this->title = '路由机制-urlManager组件-Components组件';
$this->registerMetaTag([
    'name' => 'keywords',
    'content' => 'yii,yii2,框架,应用组件,Components,使用,教程,urlManager,路由机制'
]);
$this->registerMetaTag([
    'name' => 'description',
    'content' => 'Yii的路由机制非常灵活，而urlManager的功能就是管理路由，这是Yii中必学的内容，掌握这个利器可以让您的应用变得更加优雅。'
]);

$html = [
    "概述" => <<<HTML
# 路由机制-urlManager组件的学习和使用
当入口脚本在调用 `run()` 方法时，它进行的第一个操作就是解析输入的请求，然后实例化对应的控制器动作处理这个请求。 该过程就被称为引导路由（routing）。

您需要注意的是在`urlManager`组件配置中，大多数属性都是为`Url::to()`创建url服务的，如：
- `enablePrettyUrl`： 使用`Url::to()`创建url时进行美化；
- `showScriptName`： 使用`Url::to()`创建url时，取消Url中的入口脚本名称index.php；
- `suffix`： 使用`Url::to()`创建url时添加相应的后缀（如.html）；
- `baseUrl`： 使用`Url::to()`创建url时添加指定的域名；

> 因此，如果你的目的是美化在浏览器中输入的url，请把重点放到nginx/apache的配置中，配置方法请参考：[源码安装-Url美化](/docs/install/source#pretty-url)。

HTML,
    "config" => <<<HTML
## 配置举例 id=config
urlManager组件的配置举例如下：
```php
[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true, // 美化url
            'showScriptName' => false, // 取消Url中的入口脚本名称index.php
            'rules' => [
                'dashboard' => 'site/index',
                'POST <controller:[\w-]+>' => '<controller>/create',
                '<controller:[\w-]+>s' => '<controller>/index',
                'PUT <controller:[\w-]+>/<id:\d+>'    => '<controller>/update',
                'DELETE <controller:[\w-]+>/<id:\d+>' => '<controller>/delete',
                '<controller:[\w-]+>/<id:\d+>'        => '<controller>/view',
            ]
        ]
    ],
]
```

HTML,
    "Url美化" => <<<HTML
## Url美化 id=pretty-url
我们在源码安装一节中已经介绍了如何美化url，请前往[源码安装](/docs/install/source#pretty-url)查看。

HTML,
    "严格匹配" => <<<HTML
## 严格路由模式 id=enableStrictParsing
```php
[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            'enableStrictParsing' => true, // 只有在rules中注册过的Url才允许访问 
            'rules' => [
                '/' => 'site/index',
            ]
        ]
    ],
]
```
当你开启了`'enableStrictParsing' => true`后，系统就认为只有`rules`下的路由是合法的，会屏蔽其他所有的url请求，也就是说上述配置，整个系统只有一个url可以访问。

这么做有什么好处吗？

好处就是可以显示地控制所有url路由。我们在日常开发中不自觉地会写很多无效的控制器动作（action），时间一长就会忽略对它们的管理，导致线上的用户也可以访问到，这有可能会暴露重要的数据。为了解决这个问题，您可以使用上述的配置，将可以供用户访问的url进行显示管理，这样可以有效屏蔽无效的路由。
HTML,
    "rules" => <<<HTML
## 路由规则（Rules） id=rules
`urlManager`组件并不直接参与路由规则的解析，而是调用如下两个类来完成：
- [yii\web\UrlRule](/docs/components/url-manager/web)：这是默认路由解析器，用于web请求；
- `yii\\rest\UrlRule`：这是专门给`RESTFUL API`提供了的路由解析器。

HTML,
    "create url" => <<<HTML
## 创建Url id=create-url
`urlManager`组件的一个主要功能就是提供了创建url的方法（`Url::to()`），您可以通过`url`帮助类来调用这个方法：
```php
use yii\helpers\Url;
// Url::to() 将调用 UrlManager::createUrl() 来创建URL
\$url = Url::to(['post/view', 'id' => 100]);
```
HTML,
    "index.php" => <<<HTML
### 隐藏入口脚本 id=hide-entry
在yii中，入口脚本就是`web/index.php`，在默认的url中是存在`Index.php`指定入口文件的，但是这并不优雅，因此我们可以通过下面的配置取消url中的入口脚本：
```php
[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false, // 取消入口脚本
        ]
    ],
]
```
有了上述配置，我们在创建url时就有了如下表现：
```php
// 输出：/site/index
Yii::\$app->urlManager->showScriptName = false;
echo \yii\helpers\Url::to(["site/index"]);

// 输出：/index.php/site/index
Yii::\$app->urlManager->showScriptName = true;
echo \yii\helpers\Url::to(["site/index"]);
```
HTML,
    "获取到当前页面的Url" => <<<HTML
### 当前Url id=current-url
您可以使用如下的方法获取当前页面的url：
```php
use yii\helpers\Url;
// 输出：/site/index
echo \$url = Url::to(['']);
```
但是如果您的url在`rules`中有复杂的配置，如：
```php
[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                '<page>' => '/site/contact',
            ]
        ]
    ],
]
```
上述配置中，如果您的Url后只有一层路径，那就会路由到`/site/contact`，如下：
```php
http://127.0.0.1/contact
```
此时您在`/site/contact`中输出当前的Url，就会有获得映射后的url：
```php
public function actionContact()
{
    // 输出：/site/contact
    echo Url::to([""]);
}
```
HTML,
    "域名" => <<<HTML
### 创建带域名的url id=host-info
您可以在`urlManger`中使用如下两个属性来设置域名：
- **baseUrl**
```php
Yii::\$app->urlManager->baseUrl = 'http://yii.lvzmen.com:80';
Yii::\$app->urlManager->enablePrettyUrl = true;
Yii::\$app->urlManager->showScriptName = false;
// 输出：http://yii.lvzmen.com:80/yii2/docs/users?id=100
echo \yii\helpers\Url::to(["users", 'id' => 100]);
```

- **hostInfo**  
在使用这个属性时，需要在`Url::to([], true);`第二个参数设置为true：
```php
Yii::\$app->urlManager->hostInfo = 'http://yii.lvzmen.com:80';
Yii::\$app->urlManager->enablePrettyUrl = true;
Yii::\$app->urlManager->showScriptName = false;
// 输出：http://yii.lvzmen.com:80/yii2/docs/users?id=100
echo \yii\helpers\Url::to(["users", 'id' => 100], true);
```

HTML,
    "相对路由" => <<<HTML
### 相对和绝对路由 id=absolute
`Url::to()`是根据当前上下文来确定路由的，因此如果您是在`yii2`这个module下，则会有如下表现：
- **相对路由**  
```php
Yii::\$app->urlManager->enablePrettyUrl = true;
Yii::\$app->urlManager->showScriptName = false;
// 输出： /yii2/docs/users?id=100
echo \yii\helpers\Url::to(["users", "id" => 100]);
```

- **绝对路由**
```php
Yii::\$app->urlManager->enablePrettyUrl = true;
Yii::\$app->urlManager->showScriptName = false;
// 输出： /users?id=100
echo \yii\helpers\Url::to(["/users", "id" => 100]);
```
HTML

];

//Yii::$app->urlManager->hostInfo = 'http://yii.lvzmen.com:80';
////Yii::$app->urlManager->suffix = '.html';
//Yii::$app->urlManager->enablePrettyUrl = true;
//Yii::$app->urlManager->showScriptName = false;
//echo \yii\helpers\Url::to('/images/logo.gif');die;


//echo \yii\helpers\Url::to([""]);die;
//echo '1';
//echo Yii::$app->request->setScriptUrl();die;
echo Markdown::widget(["content" => implode("\n", $html)]);

